package com.java;

import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;

/**
 * @author 黄嘉强
 */
public class Tomcat {
    /**阻塞式队列
     * 当池中线程已经到达了corePoolSize，并且这些线程都在忙，此时再有新的任务，
     * 可以将任务放入此队列中
     * */
    private static BlockingQueue<Runnable> blockingQueue=new ArrayBlockingQueue<>(100);
    /**核心线程数（池中线程数小于核心线程数时，每来一个请求都会创建一个新的线程）*/
    private static int corePoolSize=8;
    /**最大线程数（当池中线程数已经到达8，并且队列中也满了，但是这些线程都在忙，又来了新的请求，
     * 此时要继续创建线程，但最多为maximumPoolSize）*/
    private static int maximumPoolSize=256;
    /**线程空闲时间（请求并发过后，池中线程空闲了，假如长时间不使用，会造成资源浪费
     * 所以在一定时间之后，销毁空闲的线程）*/
    private static long keepAliveTime=60;
    /**时间单位*/
    private static TimeUnit timeUnit=TimeUnit.SECONDS;

    /**
     * 初始化一个线程池，通过线程池中的线程处理客户端的请求
     */
    private static ThreadPoolExecutor threadPoolExecutor=
            new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, blockingQueue);


    public static void main(String[] args) throws IOException {
        // 构建服务器对象
        ServerSocket server = new ServerSocket(9999);
        System.out.println("server start");

        // 等待客户端连接
        // 可以处理客户端的多次请求
        while(true) {
            // accept()方法会阻塞，直到有客户端连接
            Socket socket = server.accept();

            // 从线程池获取新的请求，处理多个请求
            threadPoolExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 获取网络中的输出流对象
                        OutputStream out = socket.getOutputStream();
                        String date = "HTTP/1.1 200 OK \n\r" +
                                "Content-Type: text/html;charset=utf-8 \n\r" +
                                "\n\r" +
                                "Hello Client Browser";
                        out.write(date.getBytes());
                        out.flush();
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}
